//
// Created by Luhang on 2023/5/5/005.
//

#ifndef INC_0307_LIST_H
#define INC_0307_LIST_H

#endif //INC_0307_LIST_H

#include <iostream>
#include <cassert>
using std::cout;
using std::endl;

#include "Iterator.h"

namespace Lu{
    template<class T>
    struct list_node{
        list_node<T>* _next;
        list_node<T>* _prev;
        T _data;

        explicit list_node(const T& val = T())
        :_next(nullptr)
        ,_prev(nullptr)
        ,_data(val){}
    };

    template<class T, class Ref, class Ptr>
    struct _list_iterator{
        typedef list_node<T> node;
        typedef _list_iterator<T, Ref, Ptr> self;
        node* _node;

        explicit _list_iterator(node* n)
        :_node(n){}

        Ref operator*(){
            return this->_node->_data;
        }

        //自定义类型需要用->,故重载
        Ptr operator->(){
            return &_node->_data;
        }

        self& operator++(){
            this->_node = this->_node->_next;
            return *this;
        }

        self operator++(int){
            //self tmp(this->_node);
            //调用默认拷贝构造
            self tmp(*this);
            _node = _node->_next;
            return tmp;
        }

        self& operator--(){
            _node = _node->_prev;
            return *this;
        }

        self operator--(int){
            self tmp(*this);
            _node = _node->_prev;
            return tmp;
        }

        bool operator!=(const self& s){
            return _node != s._node;
        }

        bool operator==(const self& s){
            return _node == s._node;
        }

    };

/*
    template<class T>
    struct __list_const_iterator{
        typedef list_node<T> node;
        typedef __list_const_iterator<T> self;
        node* _node;

        explicit __list_const_iterator(node* n)
                :_node(n){}

        const T& operator*(){
            return _node->_data;
        }

        self& operator++(){
            this->_node = this->_node->_next;
            return *this;
        }

        self operator++(int){
            self tmp(*this);
            _node = _node->_next;
            return tmp;
        }

        self& operator--(){
            _node = _node->_prev;
            return *this;
        }

        self operator--(int){
            self tmp(*this);
            _node = _node->_prev;
            return tmp;
        }

        bool operator!=(const self& s){
            return _node != s._node;
        }

        bool operator==(const self& s){
            return _node == s._node;
        }
    };
*/

    template<class T>
    class list{
        typedef list_node<T> node;
    public:
        typedef _list_iterator<T, T&, T*> iterator;
        typedef _list_iterator<T, const T&, const T*> const_iterator;
        typedef ReverseIterator<iterator, T&, T*> reverse_iterator;
        typedef ReverseIterator<iterator, const T&, const T*> const_reverse_iterator;

        reverse_iterator rbegin(){
            return reverse_iterator(end());
        }

        reverse_iterator rend(){
            return reverse_iterator(begin());
        }

        iterator begin(){
            //iterator it(_head->_next);
            //return it;
            //直接匿名对象
            return iterator(_head->_next);
        }

        const_iterator begin()const{
            return const_iterator(_head->_next);
        }

        iterator end(){
            return iterator(_head);
        }

        const_iterator end()const{
            return const_iterator(_head);
        }

        void empty_init(){
            _head = new node ;
            _head->_next = _head;
            _head->_prev = _head;
        }

        list(){
            empty_init();
        }

        //迭代器构造
        template<class Iterator>
        list(Iterator first, Iterator last){
            empty_init();
            while (first != last){
                push_back(*first);
                ++first;
            }
        }

        //拷贝构造
/*
        list(const list<T>& lt){
            empty_init();
            for (auto e : lt) {
                push_back(e);
            }
        }
*/

        void swap(list<T>& tmp){
            std::swap(_head, tmp._head);
        }

        list(const list<T>& lt){
            empty_init();
            list<T> tmp(lt.begin(), lt.end());
            swap(tmp);
        }

        //赋值运算符重载：拷贝构造一个临时的，然后交换给目标
        list<T>& operator=(list<T> lt){
            swap(lt);
            return *this;
        }

        ~list(){
            clear();
            delete _head;
            _head = nullptr;
        }

        void clear(){
            iterator it = begin();
            while (it != end())
                it = erase(it);
        }

        void push_back(const T& x){
/*            node* tail = _head->_prev;
            node* new_node = new node(x);
            tail->_next = new_node;
            new_node->_prev = tail;
            new_node->_next = _head;
            _head->_prev = new_node;
            */
            //end:最后一个数据的下一个
            insert(end(), x);
        }

        void push_front(const T& x){
            insert(begin(), x);
        }

        void pop_back(){
            erase(--end());
        }

        void pop_front(){
            erase(begin());
        }

        //pos的前面插入
        void insert(iterator pos, const T& x){
            node* cur = pos._node;
            node* prev = cur->_prev;

            node* new_node = new node(x);

            prev->_next = new_node;
            new_node->_prev = prev;
            new_node->_next = cur;
            cur->_prev = new_node;
        }

        iterator erase(iterator pos){
            assert(pos != end());
            node* prev = pos._node->_prev;
            node* next = pos._node->_next;
            prev->_next = next;
            next->_prev = prev;
            delete pos._node;
            return iterator(next);
        }

    private:
        node* _head;
    };

    void print_list(const list<int>& lt){
        list<int>::const_iterator it = lt.begin();
        while (it != lt.end()){
            //(*it) *= 2;
            cout << *it << " ";
            ++it;
        }
        cout << endl;
    }

    void Test1(){
        list<int> lt;
        lt.push_back(9);
        lt.push_back(6);
        lt.push_back(8);
        lt.push_back(2);

        list<int>::iterator it = lt.begin();
        while (it != lt.end()){
            (*it) *= 2;
            cout << *it << " ";
            ++it;
        }
        cout << endl;
        for (auto e : lt) {
            cout << e << " ";
        }
    }

    void Test2(){
        list<int> lt;
        lt.push_back(9);
        lt.push_back(6);
        lt.push_back(8);
        lt.push_back(2);

        print_list(lt);
    }

    struct AA{
        int _a1;
        int _a2;

        explicit AA(int a1 = 9, int a2 = 9)
        :_a1(a1)
        ,_a2(a2){}
    };

/*
    struct BB{
        int _b;
        AA aa;

        explicit BB(int b = 2)
        :_b(b){}
    };

    void Test4(){
        AA aa(6, 6);
        AA* paa = &aa;
        BB bb;
        BB* pbb = &bb;
        pbb->aa._a1 = 1;

        //paa._a1 = 6;
        paa->_a1 = 8;
        aa._a1 = 1;
        //aa->_a1 = 2;
        //(*paa)->_a1 = 5;
        (*paa)._a1 = 5;
    }
*/

//迭代器模拟的是指针行为，比如list<int>时，他就是int*，list<AA>时，它就是AA*，非node*
//所以对迭代器解引用时，就变成了it或AA，对AA：可直接->访问结构体成员变量
    void Test3(){
        list<AA> lt;
        lt.push_back(AA(1, 8));
        lt.push_back(AA(3, 6));
        list<AA>::iterator it = lt.begin();
        while (it != lt.end()){
            //*号已经运算符重载，直接返回_data
            cout << (*it)._a1 << ":" << (*it)._a2 << endl;
            cout << it->_a1 << ":" << it->_a2 << endl;
            ++it;

        }
    }

    void Test4(){
        list<int> lt;
        lt.push_back(1);
        lt.push_back(2);
        lt.push_back(3);
        lt.push_back(4);
        print_list(lt);
        auto pos = lt.begin();
        ++pos;
        lt.insert(pos, 66);
        print_list(lt);
        lt.push_back(99);
        lt.push_front(22);
        print_list(lt);
        lt.pop_back();
        lt.pop_front();
        print_list(lt);
    }

    void Test5(){
        list<int> lt;
        lt.push_back(1);
        lt.push_back(2);
        lt.push_back(3);
        lt.push_back(4);
        print_list(lt);
        list<int> lt2(lt);
        print_list(lt2);
        list<int> lt3(lt.begin(), lt.end());
        print_list(lt3);
        lt.clear();
        print_list(lt);
    }

/*
    void Test6(){
        list_node<int> new_node;
        _list_iterator<int, int&, int*>(&new_node).print_id();
        cout << typeid(float).name();
    }
*/

    void Test7(){
        list<int> lt;
        lt.push_back(1);
        lt.push_back(2);
        lt.push_back(3);
        lt.push_back(4);
        print_list(lt);
        auto pos = lt.begin();
        pos++;
        lt.insert(pos, 66);
        print_list(lt);
    }

    void Test8(){
        list<int> lt;
        lt.push_back(1);
        lt.push_back(2);
        lt.push_back(3);
        lt.push_back(4);
        print_list(lt);
        auto pos = lt.rbegin();
        while (pos != lt.rend()){
            cout << *pos << " ";
            ++pos;
        }
        cout << endl;
    }
}